bitkeeper revision 1.572 (3fabca3boPogE8eX_8H6P5qlR4SCEQ)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 7 Nov 2003 16:37:15 +0000 (16:37 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Fri, 7 Nov 2003 16:37:15 +0000 (16:37 +0000)
memory.c, xi_save_linux.c, xi_restore_linux.c:
  Moire fixes. Save/restore now works.

tools/internal/xi_restore_linux.c
tools/internal/xi_save_linux.c
xen/common/memory.c

index bd42e62952d2e5c1adffa541cb0a0085fa339f08..8ccd145d93e01832e470f14eb326cc9bda14a61b 100644 (file)
@@ -15,6 +15,13 @@ static char *argv0 = "internal_restore_linux";
 /* A table mapping each PFN to its new MFN. */
 static unsigned long *pfn_to_mfn_table;
 
+/* This may allow us to create a 'quiet' command-line option, if necessary. */
+#define verbose_printf(_f, _a...) \
+    do {                          \
+        printf( _f , ## _a );     \
+        fflush(stdout);           \
+    } while ( 0 )
+
 static int get_pfn_list(
     int domain_id, unsigned long *pfn_buf, unsigned long max_pfns)
 {
@@ -126,6 +133,7 @@ int main(int argc, char **argv)
     dom0_op_t op;
     int rc = 1, i, j;
     unsigned long mfn, pfn, dom = 0;
+    unsigned int prev_pc, this_pc;
     
     /* Number of page frames in use by this XenoLinux session. */
     unsigned long nr_pfns;
@@ -256,12 +264,22 @@ int main(int argc, char **argv)
         goto out;
     }
 
+    verbose_printf("Reloading memory pages:   0%%");
+
     /*
      * Now simply read each saved frame into its new machine frame.
      * We uncanonicalise page tables as we go.
      */
+    prev_pc = 0;
     for ( i = 0; i < nr_pfns; i++ )
     {
+        this_pc = (i * 100) / nr_pfns;
+        if ( (this_pc - prev_pc) >= 5 )
+        {
+            verbose_printf("\b\b\b\b%3d%%", this_pc);
+            prev_pc = this_pc;
+        }
+
         mfn = pfn_to_mfn_table[i];
 
         if ( !checked_read(fd, page, PAGE_SIZE) )
@@ -348,6 +366,8 @@ int main(int argc, char **argv)
     if ( flush_mmu_updates() )
         goto out;
 
+    verbose_printf("\b\b\b\b100%%\nMemory reloaded.\n");
+
     /* Uncanonicalise the suspend-record frame number and poke resume rec. */
     pfn = ctxt.i386_ctxt.esi;
     if ( (pfn >= nr_pfns) || (pfn_type[pfn] != NONE) )
@@ -446,13 +466,20 @@ int main(int argc, char **argv)
     rc = do_dom0_op(&op);
 
  out:
-    /* If we experience an error then kill the half-constructed domain. */
-    if ( (rc != 0) && (dom != 0) )
+    if ( rc != 0 )
+    {
+        if ( dom != 0 )
+        {
+            op.cmd = DOM0_DESTROYDOMAIN;
+            op.u.destroydomain.domain = dom;
+            op.u.destroydomain.force  = 1;
+            (void)do_dom0_op(&op);
+        }
+    }
+    else
     {
-        op.cmd = DOM0_DESTROYDOMAIN;
-        op.u.destroydomain.domain = dom;
-        op.u.destroydomain.force  = 1;
-        (void)do_dom0_op(&op);
+        /* Success: print the domain id. */
+        printf("DOM=%ld\n", dom);
     }
 
     return !!rc;
index 54d0a405503a77c4ec1a2f4010fef0e17a63f973..bbefaa1fb3e2dd879539edb8caefedc05980cb0b 100644 (file)
@@ -17,6 +17,13 @@ static unsigned long *pfn_to_mfn_table;
 /* A table mapping each current MFN to its canonical PFN. */
 static unsigned long *mfn_to_pfn_table;
 
+/* This may allow us to create a 'quiet' command-line option, if necessary. */
+#define verbose_printf(_f, _a...) \
+    do {                          \
+        printf( _f , ## _a );     \
+        fflush(stdout);           \
+    } while ( 0 )
+
 static int devmem_fd;
 
 static int init_pfn_mapper(void)
@@ -100,6 +107,7 @@ int main(int argc, char **argv)
     dom0_op_t op;
     int rc = 1, i, j;
     unsigned long mfn, dom;
+    unsigned int prev_pc, this_pc;
 
     /* Remember if we stopped the guest, so we can restart it on exit. */
     int we_stopped_it = 0;
@@ -319,9 +327,19 @@ int main(int argc, char **argv)
     }
     unmap_pfn(ppage);
 
+    verbose_printf("Saving memory pages:   0%%");
+
     /* Now write out each data page, canonicalising page tables as we go... */
+    prev_pc = 0;
     for ( i = 0; i < srec.nr_pfns; i++ )
     {
+        this_pc = (i * 100) / srec.nr_pfns;
+        if ( (this_pc - prev_pc) >= 5 )
+        {
+            verbose_printf("\b\b\b\b%3d%%", this_pc);
+            prev_pc = this_pc;
+        }
+
         mfn = pfn_to_mfn_table[i];
 
         ppage = map_pfn(mfn);
@@ -354,6 +372,8 @@ int main(int argc, char **argv)
         }
     }
 
+    verbose_printf("\b\b\b\b100%%\nMemory saved.\n");
+
     /* Success! */
     rc = 0;
 
index 0eb478c6ee92066cd55df3e53262f145178a8647..c2349d3240af4476397026722e398ac8c7f637a3 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/domain_page.h>
 
-#if 1
+#if 0
 #define MEM_LOG(_f, _a...) printk("DOM%d: (file=memory.c, line=%d) " _f "\n", current->domain, __LINE__, ## _a )
 #else
 #define MEM_LOG(_f, _a...) ((void)0)
@@ -395,6 +395,8 @@ static int get_twisted_l2_table(unsigned long entry_pfn, l2_pgentry_t l2e)
 
 static int get_l2_table(unsigned long page_nr)
 {
+    struct pfn_info *page;
+    struct task_struct *p;
     l2_pgentry_t *p_l2_entry, l2_entry;
     int i, ret=0;
    
@@ -424,13 +426,23 @@ static int get_l2_table(unsigned long page_nr)
     memcpy(p_l2_entry, 
            &idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
            HYPERVISOR_ENTRIES_PER_L2_PAGETABLE * sizeof(l2_pgentry_t));
-    p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
-              DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
-        mk_l2_pgentry(__pa(current->mm.perdomain_pt) | __PAGE_HYPERVISOR);
     p_l2_entry[(LINEAR_PT_VIRT_START >> L2_PAGETABLE_SHIFT) -
               DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
         mk_l2_pgentry((page_nr << PAGE_SHIFT) | __PAGE_HYPERVISOR);
 
+    /*
+     * The per-domain PGD is slightly tricky, as we may not be executing
+     * in the context of the correct domain (DOM0 builds pt's for others).
+     */
+    page = frame_table + page_nr;
+    if ( (p = find_domain_by_id(page->flags & PG_domain_mask)) != NULL )
+    {
+        p_l2_entry[(PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT) -
+                  DOMAIN_ENTRIES_PER_L2_PAGETABLE] =
+            mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR);
+        put_task_struct(p);
+    }
+
  out:
     unmap_domain_mem(p_l2_entry);
     return ret;